﻿/*
 * @author: wizardc
 */

using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using UnityEngine;

namespace DouEditor.Utils
{
    /// <summary>
    /// Json 工具类
    /// </summary>
    public static class JsonUtil
    {
        /// <summary>
        /// 编码
        /// </summary>
        public static string Encode<T>(T data, bool isFormat = false)
        {
            return JsonConvert.SerializeObject(data, isFormat ? Formatting.Indented : Formatting.None, new UnityTypeConverter());
        }

        /// <summary>
        /// 解码
        /// </summary>
        public static T Decode<T>(string json)
        {
            return JsonConvert.DeserializeObject<T>(json, new UnityTypeConverter());
        }
    }

    class UnityTypeConverter : JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            return objectType == typeof(Vector2)
                   || objectType == typeof(Vector3)
                   || objectType == typeof(Vector4)
                   || objectType == typeof(Quaternion)
                   || objectType == typeof(Color);
        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            JObject jo = new JObject();
            if (value is Vector2 vector2)
            {
                jo.Add("x", vector2.x);
                jo.Add("y", vector2.y);
            }
            else if (value is Vector3 vector3)
            {
                jo.Add("x", vector3.x);
                jo.Add("y", vector3.y);
                jo.Add("z", vector3.z);
            }
            else if (value is Vector4 vector4)
            {
                jo.Add("x", vector4.x);
                jo.Add("y", vector4.y);
                jo.Add("z", vector4.z);
                jo.Add("w", vector4.w);
            }
            else if (value is Quaternion quaternion)
            {
                jo.Add("x", quaternion.x);
                jo.Add("y", quaternion.y);
                jo.Add("z", quaternion.z);
                jo.Add("w", quaternion.w);
            }
            else if (value is Color color)
            {
                jo.Add("r", color.r);
                jo.Add("g", color.g);
                jo.Add("b", color.b);
                jo.Add("a", color.a);
            }
            jo.WriteTo(writer);
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            JObject jo = JObject.Load(reader);
            if (objectType == typeof(Vector2))
            {
                return new Vector2((float) jo["x"], (float) jo["y"]);
            }
            if (objectType == typeof(Vector3))
            {
                return new Vector3((float) jo["x"], (float) jo["y"], (float) jo["z"]);
            }
            if (objectType == typeof(Vector4))
            {
                return new Vector4((float) jo["x"], (float) jo["y"], (float) jo["z"], (float) jo["w"]);
            }
            if (objectType == typeof(Quaternion))
            {
                return new Quaternion((float) jo["x"], (float) jo["y"], (float) jo["z"], (float) jo["w"]);
            }
            if (objectType == typeof(Color))
            {
                return new Color((float) jo["r"], (float) jo["g"], (float) jo["b"], (float) jo["a"]);
            }
            return null;
        }
    }
}
